//
// Created by shaowenhan on 2020/3/7.
//

#ifndef READLRPANDWRITERESULT_READPARAMETERS_H
#define READLRPANDWRITERESULT_READPARAMETERS_H

#include <fstream>
#include <iostream>
#include <numeric>
#include "json/json.h"
#include "ParameterForRoutesRelatedProblem.h"
#include "MoveTypeAuxFunc.h"
#include "RandomNumber.h"

using namespace std;

class ReadParameters
{
private:
    static int doubleParMultiFactor(const Json::Value &value, const string& key, int factor);
    static int ceilDoubleParMultiFactor(const Json::Value &value, const string &key, int factor);
    static void exitIfValueNotInRange(const double &minimal, const double &maximal, const double &value,
                                      const string &parName);
    static double changeFactor(double maxVal, double minVal, int steps);
    static void obtainParametersForGTSControl(const Json::Value &value, ParameterForGTSControl &parameterForGTSControl,
                                              int cusNum);
    static void obtainParametersForAttTabu(const Json::Value &value, ParameterForAttTabu &parameterForAttTabu,
                                           int cusNum);
    static void obtainParametersForSolTabu(const Json::Value &value, ParameterForSolTabu &parameterForSolTabu);
    static void obtainParametersForPenaltyFactor(const Json::Value &value, ParameterForPenaltyFactor &parameterForPenaltyFactor);
    static void
    obtainParametersForGTSTermination(const Json::Value &value,
                                      ParameterForGTSTermination &parameterForGTSTermination,
                                      int cusNum, const string &suffix="");

    static void obtainParametersForDiversity(const Json::Value &value, ParameterForDiversity &parameterForDiversity,
                                             int cusNum);
    static void
    obtainParametersForRoutesPool(const Json::Value &value, ParameterForRoutesPoolControl &parameterForRoutesPool,
                                  int cusNum);
    static void
    obtainParametersForPathRelinking(const Json::Value &value,
                                     ParameterForPathRelinking &parameterForPathRelinking);
    static void
    obtainParametersForPopulation(const Json::Value &value, ParameterForPopulation &parameterForPopulation, int cusNum);
    static void
    obtainParametersForSolveStrategy(const Json::Value &value, ParameterForSolveStrategy &parameterForSolveStrategy);
    static void obtainParametersForObtainBestMoveAndGain(const Json::Value &value,
                                                         ParForObtainBestMove &parForObtainBestMove,
                                                         int cusNum);

    static void obtainParametersForMoveTypesInDifLevelOrGroup(const Json::Value &value,
                                                              vector<vector<MoveType>> &moveTypesInDifLevelOrGroup,
                                                              const string &suffix = "");
    static void obtainParametersForChooseMoveTypes(const Json::Value &value,
                                                   ParameterForChooseMoveTypes &parameterForChooseMoveTypes,
                                                   int cusNum);
    static void
    obtainParametersForAdaptiveMoveTypeChoose(const Json::Value &value,
                                              ParameterForAdaptiveMoveTypeChoose &parameterForAdaptiveMoveTypeChoose);
    static void obtainParametersForVNSBasic(const Json::Value &value, ParameterForVNS &parameterForVNS, int cusNum,
                                            const string &suffix);
    static void obtainParametersForVNS(const Json::Value &value, ParameterForVNS &parameterForVNS, int cusNum);
    static void obtainParametersForAdaptiveVNS(const Json::Value &value, ParameterForAdaptiveVNS &parForAdaptiveVNS,
                                               int cusNum);
    static void obtainParametersForGPX(const Json::Value &value, ParameterForGPX &parameterForGPX, int depotNum);
    static void
    obtainParametersForHybridAlg(const Json::Value &value, ParameterForHybridAlg &parForHybridAlg,
                                 int cusNum, int depotNum);
    static void
    obtainParametersForDisBetSol(const Json::Value &value, const string &suffix, ParameterForDisBetSol &parForDisBetSol);
    static void
    obtainParametersForFitness(const Json::Value &value, ParameterForFitness &parameterForFitness, int cusNum);
public:
    static void obtainParameters(string &filename, ParameterForRoutesRelatedProblem &parameterForRoutesRelatedProblem,
                                 int cusNum, int depotNum);
};


#endif //READLRPANDWRITERESULT_READPARAMETERS_H
